Agent-friendly documentation: .md companions, llms.txt, coding-agent guide (HF-154)#1703
Open
marcin-kordas-hoc wants to merge 36 commits into
Open
Agent-friendly documentation: .md companions, llms.txt, coding-agent guide (HF-154)#1703marcin-kordas-hoc wants to merge 36 commits into
marcin-kordas-hoc wants to merge 36 commits into
Conversation
…cking Used by the prep-flip T2.5 tier to extract the HyperFormula public API surface at a given git ref and compare between develop and PR HEAD to detect breaking API changes (constructor arg additions, removed exports, lint-scope drift).
…int config Add scripts/*.js override to .eslintrc.js enabling node env and disabling TypeScript-specific rules that do not apply to CJS scripts. Auto-fix semicolons (project enforces no-semicolons style), rename lint_scope variable to lintScope (naming-convention), and add missing JSDoc param/returns descriptions.
Five-component design: VuePress md-companions plugin, Copy Markdown button, static setup-coding-agent page, interactive wizard, and llms.txt/robots.txt updates. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Address 5 findings grounded in VuePress core verification: - respect base '/docs/' and DOCS_DEST in all 5 components - compute Copy Markdown URL from $page.path, not window.location - forbid invented install commands; trace to published skill - token-aware container stripping with code-fence fixture test - flag robots.txt root-vs-/docs/ placement for confirmation Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Six tasks: md-companions plugin (C1), Copy Markdown button (C2), setup-coding-agent page (C3), interactive wizard (C4), llms.txt/robots (C5), and config.js integration. Install commands traced to the published handsontable/handsontable-skills repo; code-fence stripping fixture test included. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Install commands traced to handsontable/handsontable-skills; no invented commands. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…mpanions Strip.js regex was limited to tip|warning|danger|details. The ::: example container (live code runner) leaked into companion .md files. Broadened match to \w+ and strip example containers entirely (they are demo markup, not prose). Added 8th assertion to the test fixture. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…p page - require md-companions plugin, register with DOCS_HOSTNAME - globalUIComponents: ['CopyMarkdownButton'] - add 'Set up your coding agent' to Getting started sidebar Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
strip.js: - track full fence marker length (CommonMark); inner ``` no longer closes ```` - bail out verbatim on unclosed ::: container (no silent page truncation) - 9th test assertion for nested fence lengths index.js: - wrap per-page work in try/catch; one bad page warns and continues - substitute real base/hostname in corpus header (was literal <base>) CopyMarkdownButton.vue + CodingAgentWizard.vue: - clipboard fallback via document.execCommand for non-HTTPS contexts - isSecureContext guard + .catch() on Clipboard API promise - null-guard on this.current in wizard copy() setup-coding-agent.md: - relative links to llms-full.txt (../llms-full.txt) to survive any base-path edge cases in static-file link resolution Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The md-companions markdown stripper is the acceptance gate for the agent-friendly docs (per-page .md companions + llms.txt), but its test lived at docs/.vuepress/plugins/md-companions/strip.test.js — a path and suffix Jest's testMatch (`test/**/*spec.(ts|js)`) never discovers, so it never ran in CI. - Move the assertions into test/docs/md-companions-strip.spec.js as a Jest spec, where the default glob picks them up. The file is `.js`, so Karma's `.spec.ts`-only require.context skips it (the stripper is plain Node code, not part of the browser bundle). - Add an ESLint override for `**/test/**/*.spec.js` mirroring the existing `scripts/*.js` relaxations (node env, allow require of untyped modules). - Remove the orphan strip.test.js. - CHANGELOG: note the agent-friendly docs under [Unreleased] > Added. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
These are internal implementation planning docs, not user-facing documentation. VuePress builds every file under docs/ into the public site (and the md-companions plugin would emit .md + llms.txt for them), so they must not live in the public repo. They belong in the internal dev-skills workspace instead.
…rve-out scripts/extract-public-api.js was an internal helper for the prep-flip review harness (per its own header), has no consumer anywhere in this repo, and is out of scope for an agent-friendly-docs PR. Removing it also resolves the two outstanding review threads it was the sole source of: the CodeQL 'indirect uncontrolled command line' alert (execSync git show) and Cursor's regex finding in extractHyperFormulaExports. The scripts/*.js ESLint override existed only to lint this file, so it is removed too; the **/test/**/*.spec.js override stays (needed by the md-companions strip spec). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Contributor
|
Task linked: HF-154 Agent-friendly docs |
✅ Deploy Preview for hyperformula-dev-docs ready!
To edit notification comments on pull requests, go to your Netlify project configuration. |
marcin-kordas-hoc
added a commit
that referenced
this pull request
Jul 9, 2026
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
e79f1a8 to
ddfa8f0
Compare
Performance comparison of head (1836e1e) vs base (033f8ac) |
The docs build (`npm run docs:build`) is validated in CI on Node 22 (the build-docs workflow), but Netlify built the deploy preview on Node 18, where the build errored. Aligning the deploy runtime with the validated CI runtime. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ents - CopyMarkdownButton copies the page's .md URL (per its tooltip), so the label now reads 'Copy Markdown link' instead of 'Copy Markdown', which implied it copied the markdown content. Guide reference updated to match. - Removed the two 'AI/LLM agent index' comment lines from robots.txt: crawlers ignore comments, so they provided no machine-discoverability. llms.txt is discoverable at its well-known path; the Sitemap directive stays. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Verified the deploy-preview build output: llms-full.txt is populated (1.3 MB, page content present) and guide pages strip cleanly, but the typedoc API pages leaked ~638 inline `<Badge text="Class"/>` tags — the stripper only dropped component tags that occupied a whole line, not inline ones after heading text. Now strips inline self-closing capitalized components too; the [A-Z] guard leaves plain HTML (<br/>) alone and code fences are still preserved. +3 spec assertions (12 total). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ent tags - Extract the shared Clipboard-API-with-textarea-fallback logic from CopyMarkdownButton.vue and CodingAgentWizard.vue into a single components/clipboard.js (copyToClipboard); both now import it. - strip.js: also drop a whole-line closing tag of a paired block component (</Foo>); the opening tag and inner content were already handled, only the stray closing tag leaked. +1 spec assertion (13). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4 tasks
…teness, root llms.txt) Review (line/function/module + agentic-QE) surfaced these; all verified: - strip.js: a single-line <script>…</script>/<style> no longer opens a multi-line skip that swallowed following content (repro'd). - strip.js: blank-line collapse is now fence-aware — 3+ blank lines inside a code fence are preserved (were mutated). - index.js: include clean-URL / directory pages (home, section indexes) in the corpus, not just *.html (they were silently absent); the final llms-full.txt write is now best-effort (warns) like the per-page writes. - CopyMarkdownButton.vue: hide on /404.html (was offering a .md URL that 404s). - netlify.toml: rewrite root /llms.txt and /llms-full.txt to the built files under /docs/, so agents probing the well-known path resolve (base is /docs/). - tests: +generated() spec (fs mocked) covering per-page + corpus writes, dir-page inclusion, per-page error isolation, corpus-write resilience, empty content, URL/base construction; +3 strip regression tests (17 total). clipboard.js/.vue unit tests deferred (need jest-ESM/vue-test-utils infra). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Honours the 'always resolves' contract even if the textarea/execCommand fallback path throws (detached document, disabled command) — addresses the review note that a throwing fallback broke the promise contract. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
f83947c to
76c3f14
Compare
Directory/clean-URL pages emit their companion as <dir>/index.md, so 'append .md to any docs URL' over-claimed. Reword to 'a docs page URL' with an example, in both the setup guide and the llms-full.txt header. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…covery)
- strip.js: neutralise VuePress-only markup that leaked into companions —
{{ }} interpolations, Vue-bound <a :href>/<img :src> tags (keep anchor
text, drop images). (#3, #8)
- index.js: mirror llms.txt + llms-full.txt to the served ROOT
(dirname(outDir)) so /llms.txt resolves on GitHub Pages prod, where
netlify.toml redirects don't apply. (#5)
- CopyMarkdownButton.vue: also show on directory/landing pages (→ index.md),
matching the plugin's companion output. (#4)
- tests: +4 strip assertions (mustache, bound anchor/img, fence-safety) and
generated() now asserts the root mirror. 26/26.
Already-addressed Bugbot notes (earlier commits): homepage inclusion (#1),
404 button hidden (#2/404), per-page .md wording (#6/#7).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…t-friendly-docs # Conflicts: # CHANGELOG.md
Cursor Bugbot flagged that stripping {{ … }} drops meaningful inline values
(e.g. a function count) — worse than shipping the literal token. Leave them
as-is; full expansion needs rendered-HTML extraction (follow-up). The
Vue-bound <a :href>/<img :src> stripping (no info loss) stays.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bugbot: context7.json only excluded docs/.vuepress/dist, so Context7 would index the VuePress source (config, plugins, .vue components) as if it were HyperFormula documentation. Exclude the whole docs/.vuepress; the actual guide content lives under docs/guide/ and docs/*.md. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bugbot: the [[toc]] removal only matched whole-line markers, so inline forms like '**Contents:** [[toc]]' (custom-functions.md) leaked into companions. Now stripped anywhere. +1 spec assertion. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 861c816. Configure here.
Bugbot: /docs/guide/ has no static index (client-side Vue Router only), so raw fetches 404 for non-JS agents. Point the Guide entry at the docs root /docs/ (returns 200), which is stable across page renames. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The snippet box inherited a near-invisible light text colour on its light background. Set explicit dark text (#2c3e50, VuePress $textColor), reset the inner <code> colour/background, and wrap long URLs (word-break) so the full llms-full.txt link is visible instead of overflowing. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ompanions Reviewing the live basic-usage.md companion: the '## Demo' heading dangled at EOF because its :::example live-demo was (correctly) stripped, leaving an empty trailing section; and a whitespace-only source line surfaced as literal spaces. Now: trailing heading(s) with no body are dropped (guarded by a hasProse check so a title-only page like '# AbsoluteCellRange' is never wiped), and whitespace-only lines are normalised to clean blanks. +2 spec assertions (29). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Stratified whole-page fixtures (one per real docs category: guide+tip+demo,
integration with {{ }}+Vue anchor, branding image, API page with <Badge>,
fence-preservation, title-only) run through the stripper with 'clean companion'
invariants — no VuePress/Vue leaks outside fences, no dangling empty heading.
Encodes the bug classes found on the live preview as regressions. 35 assertions.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## develop #1703 +/- ##
========================================
Coverage 97.15% 97.15%
========================================
Files 176 176
Lines 15404 15404
Branches 3409 3409
========================================
Hits 14966 14966
Misses 438 438 🚀 New features to boost your workflow:
|
The wizard snippet used a light box while the rest of the docs' code blocks are dark ($codeBgColor #282c34), so it looked inconsistent on the same page (visible on the Set-up-your-coding-agent page). Match the fenced-code-block style: dark bg + light text. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.

Context
HF-154 — make the HyperFormula docs friendlier to coding agents and LLMs. On top of the existing VuePress portal this adds:
.mdcompanions — every doc page is also served as clean, VuePress-stripped Markdown (a build-timemd-companionsplugin), plus an aggregatellms-full.txt. Both are also mirrored to the site root so/llms.txtand/llms-full.txtresolve on GitHub Pages (prod) and the Netlify preview.llms.txt— a top-level index pointing agents at the Markdown sources.CopyMarkdownButton.vue) — copies the page's.mdURL for pasting into an agent.docs/guide/setup-coding-agent.md) plus aCodingAgentWizard.vuehelper.context7.jsonso agent doc-access tooling (Context7 / GitMCP) can discover the sources.The Markdown stripper (
md-companions/strip.js) is the fidelity-critical piece: it turns VuePress-flavoured Markdown (:::containers,<script>/Vue components,[[toc]],{{ }}bindings, Vue-bound<a :href>/<img :src>, live:::exampledemos, nested code fences) into clean Markdown.How did you test your changes?
test/docs/(26 assertions, all passing):md-companions-strip.spec.jscovers the stripper's transforms and edge cases;md-companions-generated.spec.jscovers thegenerated()hook (per-page writes, root mirror, per-page error isolation, empty content, URL/base construction) withfsstubbed. Both are.jsJest specs (Karma globs only.spec.ts, so they stay out of the browser bundle).npm run lintclean (an ESLint override for**/test/**/*.spec.jsallows the plain-Node specs).llms-full.txtpopulated, per-page.mdclean, no leaked components).Types of changes
Related issues:
Checklist:
Notes
hyperformula-testsrepo). Currentdevelopis merged in.md-companionsplugin and.vuecomponents are VuePress-specific); the agent-friendly outputs (.mdcompanions,llms.txt, setup guide) would need re-homing in Astro.Note
Low Risk
Changes are limited to documentation build tooling, static assets, and tests; the spreadsheet engine runtime is untouched.
Overview
Adds LLM/agent-oriented documentation on top of the existing VuePress site: a build-time
md-companionsplugin strips VuePress/Vue syntax and emits per-page.mdcompanions,llms-full.txt, and mirrorsllms.txt/ corpus to the site root for GitHub Pages and Netlify.The docs UI gains a global Copy Markdown link button, a coding-agent setup guide with
CodingAgentWizard, sidebar entry, staticllms.txt, and rootcontext7.json. Netlify bumps Node to 22 and adds root rewrites for/llms.txtand/llms-full.txt; ESLint relaxes rules for plain-Nodetest/**/*.spec.jsspecs covering the stripper andgenerated()hook.Reviewed by Cursor Bugbot for commit 2fca6ee. Bugbot is set up for automated code reviews on this repo. Configure here.